package com.magic.babyphotos;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.magic.babyphotos.dialog.LoadingDialog;
import com.magic.babyphotos.widget.PhotoSortrView;
import com.meishizhi.lib.effect.Filters;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
//import android.media.ExifInterface;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;

import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectory;

public class EditActivity extends BaseActivity implements OnTouchListener
{
    private static int SCREEN_HEIGHT = 0;

    private static int SCREEN_WIDTH = 0;
    
    private Matrix matrix = new Matrix();
    
    private static Bitmap tmp;
    
    private float density = 1;
    
    public static final int ORIENTATION_UNDEFINED = 0;
    public static final int ORIENTATION_NORMAL = 1;
    public static final int ORIENTATION_FLIP_HORIZONTAL = 2;  // left right reversed mirror
    public static final int ORIENTATION_ROTATE_180 = 3;
    public static final int ORIENTATION_FLIP_VERTICAL = 4;  // upside down mirror
    public static final int ORIENTATION_TRANSPOSE = 5;  // flipped about top-left <--> bottom-right axis
    public static final int ORIENTATION_ROTATE_90 = 6;  // rotate 90 cw to right it
    public static final int ORIENTATION_TRANSVERSE = 7;  // flipped about top-right <--> bottom-left axis
    public static final int ORIENTATION_ROTATE_270 = 8; 
    
//    private FrameLayout editContainer;
   
    
    private Object frame;
    
    private int frame_width;
    private int frame_height;
    
    private static final int DIALOG_SAVE = 1;
    private static final int DIALOG_SD_NOT_EXIST = 2;
    
//    private ArrayList<ImageViewTouch> stamps;
    
//    private ImageViewTouch selectedStamps;
    
    private PhotoSortrView itemsContainer;
    
    private SaveDialog saveDialog;

    private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();

    public void onCreate(Bundle bundle)
    {
        super.onCreate(bundle);
        this.setContentView(R.layout.edit_layout);
        init();
        initUI();
    }
    
    protected void onNewIntent(Intent intent) 
    {
        String action = intent.getAction();
        if(intent != null && action != null)
        {
            if(AppConstants.ACTION_SELECT_FRAME.equals(action))
            {
                int frame_index = intent.getIntExtra(AppConstants.KEY_SELECTED_FRAME, -1);
                if(frame_index == 20)
                {
                	if(frame != null)
                	{
                		itemsContainer.removeImg(frame);
                		frame = null;
                		itemsContainer.setOutputHeight(0);
                        itemsContainer.setOutputWidth(0);
                	}
                }
                else if(frame_index >= 0)
                {
                    int resId = AppConstants.FRAME_IMAGE_IDS[frame_index];
                    if(frame != null)
                    	itemsContainer.removeImg(frame);
//                    frame = new ImageView(EditActivity.this);
//                    frame.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
//                            LayoutParams.WRAP_CONTENT));
//                    frame.setImageResource(resId);
    
                    frame = itemsContainer.addImg(resId, false, false);
                    itemsContainer.setOutputHeight(frame_height);
                    itemsContainer.setOutputWidth(frame_width);
                }
            }
            else if(AppConstants.ACTION_SELECT_STAMP.equals(action))
            {
                int category = intent.getIntExtra(AppConstants.KEY_SELECTED_CATEGORY, 0);
                int position = intent.getIntExtra(AppConstants.KEY_SELECTED_STAMP, 0);
                int resId = AppConstants.STAMP_IMAGES_IDS[category][position];
                
//                selectedStamps = new ImageViewTouch(EditActivity.this);
//                selectedStamps.setItem(true);
//                selectedStamps.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
//                    LayoutParams.WRAP_CONTENT));
//                selectedStamps.setImageResource(resId);
//                selectedStamps.setScaleType(ScaleType.MATRIX);
//                selectedStamps.setOnClickListener(this);
//
//                editContainer.addView(selectedStamps);
//                stamps.add(selectedStamps);
                
                itemsContainer.setVisibility(View.VISIBLE);
                itemsContainer.addImg(resId, true, true);
                
            }
        }
    }

    private void init()
    {
        SCREEN_WIDTH = getWindowManager().getDefaultDisplay().getWidth();
        SCREEN_HEIGHT = getWindowManager().getDefaultDisplay().getHeight();
        if(SCREEN_WIDTH > SCREEN_HEIGHT)
        {
            int tmp = SCREEN_HEIGHT;
            SCREEN_HEIGHT = SCREEN_WIDTH;
            SCREEN_WIDTH = tmp;
        }
        DisplayMetrics metric = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metric);
        density  = metric.density;
        
//        stamps = new ArrayList<ImageViewTouch>();
    }

    private void initUI()
    {
    	itemsContainer = (PhotoSortrView)findViewById(R.id.items_container);
        initRawPhoto();
        
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), AppConstants.FRAME_IMAGE_IDS[0]);
        
        frame_width = bmp.getWidth();
        frame_height = bmp.getHeight();
        
        View bt_back = this.findViewById(R.id.bt_back);
	    bt_back.setOnClickListener(this);
	    bt_back.setOnTouchListener(this);
	    
//	    editContainer = (FrameLayout)findViewById(R.id.edit_container);
	    
	    findViewById(R.id.bt_frame).setOnClickListener(this);
	    findViewById(R.id.bt_frame).setOnTouchListener(this);
	    
	    findViewById(R.id.bt_item).setOnClickListener(this);
	    findViewById(R.id.bt_item).setOnTouchListener(this);
	    
//	    findViewById(R.id.bt_pen).setOnClickListener(this);
//	    findViewById(R.id.bt_pen).setOnTouchListener(this);
	    
	    findViewById(R.id.bt_delete).setOnClickListener(this);
	    findViewById(R.id.bt_delete).setOnTouchListener(this);
	    
	    findViewById(R.id.bt_save).setOnClickListener(this);
	    findViewById(R.id.bt_save).setOnTouchListener(this);
	    
    }
    
    private void initRawPhoto()
    {
        try
        {
            InputStream localInputStream = this.getContentResolver().openInputStream(
                Uri.parse(getIntent().getStringExtra("selected_image")));

//            ExifInterface exif = null;
            
            Directory exifDirectory = null;
            
            try
            {
                Metadata metadata = JpegMetadataReader.readMetadata(new File(getIntent().getStringExtra("selected_path")));
                exifDirectory = metadata.getDirectory(ExifDirectory.class);
                
//                exif = new ExifInterface(getIntent().getStringExtra("selected_path"));
            }
            catch (Exception e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            int orientation = 0;//exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            if(exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION))
            {                
                try
                {
                    orientation = exifDirectory
                            .getInt(ExifDirectory.TAG_ORIENTATION);
                }
                catch (Exception e)
                {
                }
                ;
            }
            int nextWidth = 0;
            int nextHeight = 0;
            
//            
            if(orientation == ORIENTATION_NORMAL || orientation == ORIENTATION_ROTATE_180)
            {
                try
                {
                nextWidth = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);//exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
                nextHeight = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);//exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
                }catch(Exception e){};
            }
            else
            {
                try
                {
                    nextHeight = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);//exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
                    nextWidth = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);//exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
                }catch(Exception e){};
            }
            if(nextHeight == 0 || nextWidth == 0)
            {
            	sBitmapOptionsCache.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(localInputStream, null, sBitmapOptionsCache);
                nextHeight = sBitmapOptionsCache.outHeight;
                nextWidth = sBitmapOptionsCache.outWidth;
                try {
					localInputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
            int sampleSize = 1;
            while (nextWidth > SCREEN_WIDTH && nextHeight > SCREEN_HEIGHT)
            {
                sampleSize <<= 1;
                nextWidth >>= 1;
                nextHeight >>= 1;
            }
            sBitmapOptionsCache.inSampleSize = sampleSize;
            sBitmapOptionsCache.inJustDecodeBounds = false;
            
            localInputStream = this.getContentResolver().openInputStream(
                Uri.parse(getIntent().getStringExtra("selected_image")));
            
            Bitmap bitmap = BitmapFactory.decodeStream(localInputStream, null,
                sBitmapOptionsCache);

            int destHeight = SCREEN_HEIGHT;
            int destWidth = 0;
            
            if(sampleSize > 1)
            {
	            if(orientation == ORIENTATION_NORMAL || orientation == ORIENTATION_ROTATE_180)
	            {
	                
	                destWidth = nextHeight > SCREEN_HEIGHT ? (int) ((float) bitmap.getWidth()
	                        * (float) nextHeight / (float) SCREEN_HEIGHT) : (int) ((float) bitmap
	                                .getWidth() * (float) SCREEN_HEIGHT / (float) nextHeight);
	            }
	            else
	            {
	                destWidth = nextHeight > SCREEN_HEIGHT ? (int) ((float) bitmap.getWidth()
	                        * (float) nextHeight / (float) SCREEN_HEIGHT) : (int) ((float) bitmap
	                                .getHeight() * (float) SCREEN_HEIGHT / (float) nextHeight);
	            }
            }
            else
            {
            	destHeight = nextHeight;
            	destWidth = nextWidth;
            }

            switch(orientation)
            {
                case ORIENTATION_NORMAL:
                {
                    matrix.postRotate(0);
                    break;
                }
                case ORIENTATION_ROTATE_90:
                {
                    matrix.postRotate(90);
                    break;
                }
                case ORIENTATION_ROTATE_180:
                {
                    matrix.postRotate(180);
                    break;
                }
                case ORIENTATION_ROTATE_270:
                {
                    matrix.postRotate(270);
                    break;
                }
            }
            
            tmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//            int width = tmp.getWidth();
//            int height = tmp.getHeight();
//            int pixels[] = new int[width * height];
//            tmp.getPixels(pixels, 0, width, 0, 0, width, height);
//            Filters.nashville(pixels, width, height);
//            tmp =  Bitmap.createBitmap(pixels, width, height, tmp.getConfig());
            
            Bitmap scale = Bitmap.createScaledBitmap(tmp, destWidth, destHeight, true);
//            ((ImageViewTouch) this.findViewById(R.id.editimage)).setImageBitmap(scale);
            itemsContainer.addImg(new BitmapDrawable(scale), false, true);
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        switch(v.getId())
        {
            case R.id.bt_frame:
            {
                changeAlpha(v, event.getAction());
                break;
            }
            case R.id.bt_item:
            {
                changeAlpha(v, event.getAction());
                break;
            }
//            case R.id.bt_pen:
//            {
//                changeAlpha(v, event.getAction());
//                break;
//            }
            case R.id.bt_delete:
            {
                changeAlpha(v, event.getAction());
                break;
            }
            case R.id.bt_save:
            {
                changeAlpha(v, event.getAction());
                break;
            }
            
        }
        
        return super.onTouch(v, event);
    }
    
    @Override
    public void onClick(View v)
    {
        switch(v.getId())
        {
            case R.id.bt_frame:
            {
                Intent intent = new Intent(EditActivity.this, FrameChooseActivity.class);
                startActivity(intent);
                return;
            }
            case R.id.bt_item:
            {
                Intent intent = new Intent(EditActivity.this, StampActivity.class);
                startActivity(intent);
                return;
            }
//            case R.id.bt_pen:
//            {
//                return;
//            }
            case R.id.bt_delete:
            {
                itemsContainer.removeLast();
                return;
            }
            case R.id.bt_save:
            {
                if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                {
                    showDialog(DIALOG_SAVE);
                }
                else
                {
                    showDialog(DIALOG_SD_NOT_EXIST);
                }
                return;
            }
            default:
            {
//                if(stamps.contains(v))
//                {
//                    this.selectedStamps = (ImageViewTouch)v;
//                }
            }
        }
        
        super.onClick(v);
    }
    
    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        if(tmp != null)
        {
            tmp.recycle();
            tmp = null;
        }
    }
    
    protected Dialog onCreateDialog(int id) 
    {
        switch(id)
        {
            case DIALOG_SAVE:
            {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle(getResources().getString(R.string.save_dialog_title));
                builder.setMessage(getResources().getString(R.string.save_dialog_msg))
                        .setPositiveButton(getResources().getString(R.string.save), new DialogInterface.OnClickListener()
                        {
                            public void onClick(DialogInterface dialog, int id)
                            {
                                saveDialog = new SaveDialog(EditActivity.this, R.string.saving, R.string.save_error);
                                saveDialog.execute();
                            }
                        }).setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
                        {
                            public void onClick(DialogInterface dialog, int id)
                            {
                            }
                        });
                AlertDialog alert = builder.create();

                return alert;
            }
            case DIALOG_SD_NOT_EXIST:
            {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage(getResources().getString(R.string.sd_not_exist))
                        .setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
                        {
                            public void onClick(DialogInterface dialog, int id)
                            {
                            }
                        });
                AlertDialog alert = builder.create();

                return alert;
            }
        }
        return super.onCreateDialog(id);
    }
    
    public boolean onSaveClick(String filePath)
    {
        Bitmap bmp = itemsContainer.getCanvasSnapshot();
        boolean result = false;
        if (null != bmp)
        {
            result = saveBitmapToSDCard(bmp, filePath);
//            fileScan(strFilePath);
//            new MediaScannerNotifier(this, strFilePath);
        }
        
        return result;
    }
    
    public void fileScan(String fName)
    {  
        Uri data = Uri.parse("file:///"+fName);  
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));  
    }
    
    public static String getOutputFilePath()
    {
        (new File("/DCIM/Camera")).mkdirs();
        return Environment.getExternalStorageDirectory() + "/DCIM/Camera/" + "Babyphotos_" + System.currentTimeMillis() + ".jpg"; 
    }
    
    public static boolean saveBitmapToSDCard(Bitmap bmp, String strPath)
    {
        if (null != bmp && null != strPath && !strPath.equalsIgnoreCase(""))
        {
            try
            {
                File file = new File(strPath);
                FileOutputStream fos = new FileOutputStream(file);
                byte[] buffer = Bitmap2Bytes(bmp);
                fos.write(buffer);
                fos.flush();
                fos.close();
                return true;
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
                return false;
            }
            catch (IOException e)
            {
                e.printStackTrace();
                return false;
            }
        }
        
        return false;
    }
    
    private static byte[] Bitmap2Bytes(Bitmap bm) 
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }
    
    class SaveDialog extends LoadingDialog<Void, Void, Boolean> implements MediaScannerConnectionClient
    {
        private ConditionVariable mCondition;
        private MediaScannerConnection mConnection;
        String path;
        
        public SaveDialog(Activity activity, int loadingMsg, int failMsg)
        {
            super(activity, loadingMsg, failMsg);
            this.mCondition = new ConditionVariable(false);
            mConnection = new MediaScannerConnection(activity, this);
        }

        @Override
        public Boolean doInBackground(Void... params)
        {
            // TODO Auto-generated method stub
            path = getOutputFilePath();
            boolean result = onSaveClick(path);
            mConnection.connect();
            mCondition.block();
            return result;
        }

        @Override
        public void doStuffWithResult(Boolean result)
        {
            // TODO Auto-generated method stub
            if(isCancelled())
                return;
            Toast.makeText(mActivity, R.string.saved_to_sd, 2000).show();
            finish();
            Intent intent = new Intent(EditActivity.this, ShareActivity.class);
            intent.putExtra("result_path", path);
            startActivity(intent);
        }

        @Override
        public void onMediaScannerConnected()
        {
            mConnection.scanFile(path, "image/jpeg");
            
        }

        @Override
        public void onScanCompleted(String path, Uri uri)
        {
            // TODO Auto-generated method stub
            mConnection.disconnect();
            mCondition.open();
        }
        
    }
}
